﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Legend.Object;
using Legend.Component.Common;
using Legend.Component.Monster;
using Legend.Component.Interface;
using Legend.Component.Prop;
using Legend.Component.PowerBall;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.IO;

namespace LegendMain.TestBed
{
    struct PropGenerationJob : IComparable<PropGenerationJob>
    {
        public Vector3 Position;
        public GameObject Prop;

        public int CompareTo(PropGenerationJob other)
        {
            return (int)(Position.Y - other.Position.Y);
        }
    };

    public static class PropGenerator
    {
        private static ContentManager contentManager;
        private static Queue<PropGenerationJob> jobQueue = new Queue<PropGenerationJob>();
        private static Dictionary<string, Model> models = new Dictionary<string, Model>();
        private static List<GameObject> boxList = new List<GameObject>();

        public static Model FindModel(string model)
        {
            if (!models.ContainsKey(model))
            {
                models[model] = contentManager.Load<Model>(model);
            }

            return models[model];
        }

        public static void Initialize(ContentManager manager)
        {
            List<PropGenerationJob> list = new List<PropGenerationJob>();
                        
            contentManager = manager;
            char[] seperator = new char[] { ',' };

            using (StreamReader reader = new StreamReader(File.Open("BoxDeploy.txt", FileMode.Open)))
            {
                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine();
                    line.Trim();

                    if (line.StartsWith("//"))
                    {
                        continue;
                    }

                    string[] tokens = line.Split(seperator);
                    if (tokens.Length < 2)
                    {
                        continue;
                    }

                    string modelName = tokens[0].Trim();
                    GameObject box = new GameObject();
                    PropGenerationJob job = new PropGenerationJob();
                    job.Prop = box;

                    if (modelName == "box01")
                    {
                        LinearMovement movement = box.CreateComponent<LinearMovement>();
                        movement.Velocity = new Vector3(0, -100, 0);
                        movement.Position = new Vector3(float.Parse(tokens[1]), float.Parse(tokens[2]), 10);
                        job.Position = movement.Position;

                        if (tokens.Length < 4 || string.Compare(tokens[3].Trim(), "hidden", true) != 0)
                        {
                            SimpleRenderable renderable = box.CreateComponent<SimpleRenderable>();
                            renderable.Model = FindModel(modelName);

                            Collision collision = box.CreateComponent<Collision>();
                            collision.LocalBoundingBox = Legend.Helper.Mesh.GetModelBoundingBox(renderable.Model);
                            collision.CollisionType = ICollision.CollisionTypes.Block;
                        }

                        BoxDamaging damaging = box.CreateComponent<BoxDamaging>();
                        damaging.Damage = 10;

                        boxList.Add(box);
                    }
                    else if (modelName == "p_box")
                    {
                        LinearMovement movement = box.CreateComponent<LinearMovement>();
                        movement.Velocity = new Vector3(0, -60, 0);
                        movement.Position = new Vector3(float.Parse(tokens[1]), float.Parse(tokens[2]), 30);
                        movement.Rotate(Vector3.Right, (float)Math.PI / 4f);
                        job.Position = movement.Position;

                        SimpleRenderable renderable = box.CreateComponent<SimpleRenderable>();
                        renderable.Model = FindModel(modelName);
                        
                        PowerBallDamaging damaging = box.CreateComponent<PowerBallDamaging>();
                        damaging.Damage = 10;

                        Collision collision = box.CreateComponent<Collision>();
                        collision.LocalBoundingBox = Legend.Helper.Mesh.GetModelBoundingBox(renderable.Model);
                        collision.CollisionType = ICollision.CollisionTypes.Through;
                    }
                    list.Add(job);
                }

                list.Sort();
                foreach (PropGenerationJob job in list)
                {
                    jobQueue.Enqueue(job);
                }
            }
        }

        public static void Update(GameTime gameTime)
        {
            while (jobQueue.Count > 0)
            {
                Vector3 propPosition = jobQueue.Peek().Position;
                propPosition.Y -= (float)(gameTime.TotalGameTime.TotalMilliseconds * 100 / 1000);

                if (GameObjectManager.ViewFrustum.Contains(propPosition) == ContainmentType.Contains)
                {
                    PropGenerationJob job = jobQueue.Dequeue();

                    GameObjectManager.RegistGameObject(job.Prop);
                }
                else
                {
                    break;
                }
            }

            //foreach (GameObject box in boxList)
            //{
            //    ICollision collision = box.FindComponent<ICollision>();

            //    if (collision != null)
            //    {
            //        Console.WriteLine(collision.BoundingBox);
            //    }
            //}

        }
    }
}
